
(tree-reduce 
 + 
 0 
 '(0 (1 2) (3 (4 5) 6) 7 (8) 9))	; => 45

(tree-reduce 
 min 
 0 
 '(1 (7) (2 (-5 3) 8)))			; => -5

(tree-map - '(1 (2 3) (4 (5 6))))	; => (-1 (-2 -3) (-4 (-5 -6)))

(tree-map/depth 0 xcons '(1 (2 3) (4 (5 6))))

;; => ((1 . 0) ((2 . 1) (3 . 1)) ((4 . 1) ((5 . 2) (6 . 2))))

(tree-map* (lambda (e) (if (list? e)  (reverse e) e))
	   '(1 (2 3) (4) 5))

;; => (1 (4) 5 (3 2))

;; A depth based ordering

(let ((t '(1 (2 3) (4 (5 6)))))
  (map cdr 
       (sort (tree-walk identity (tree-map/depth 0 cons t))
	     (lambda (a b) (> (car a) (car b))))))

;; => (5 6 2 3 4 1)

;; A 'topological' sort.

(let ((t '(1 (2 (3 (4 5) 6) 7 8) 9)))
  )

(tree-walk 
 (lambda (element) 
   (cons element (= 0 (modulo element 2))))
 '(0 (1 2) (3 (4 5) 6) 7 (8) 9))	

;; => ((0 . #t) (1 . #f) (2 . #t) (3 . #f) ...)

(tree-leaves 
 '(0 (1 2) (3 (4 5) 6) 7 (8) 9))	; => (0 1 2 3 4 5 6 7 8 9)

(tree-map 
 abs 
 '(0 (-1 2) (-3 (4 -5) 6) -7 (8) -9))   ; => (0 (1 2) (3 (4 5) 6) 7 (8) 9)

(tree-remove even? '(0 7 8 8 43 -4))	; => (7 43)

(define (all-equal? a b . c)
  (and (equal? a b)
       (if (null? c) #t (apply all-equal? b c))))

(append
 (tree-remove (lambda (x) 
		(and (integer? x) (even? x))) 
	      '(0 (7 8) (8 (43 -4))))
 (tree-remove-leaves even? '(0 (7 8) (8 (43 -4))))
 (tree-filter (lambda (x) 
		(or (list? x) (odd? x))) 
	      '(0 (7 8) (8 (43 -4))))
 (tree-filter-leaves odd? '(0 (7 8) (8 (43 -4)))))

;; => ((7) ((43)) (7) ((43)) (7) ((43)) (7) ((43)))

(tree-find 
 (lambda (tree)
   (and (list? tree) (member 5 tree)))
 '(0 (1 2) (3 (4 5) 6) 7 (8) 9))	; => (4 5)

(tree-find 
 (lambda (tree)
   (and (tree-leaf? tree) (= tree 5)))
 '(0 (1 2) (3 (4 5) 6) 7 (8) 9))	; => 5

(tree-find-leaf
 (=?? 5)
 '(0 (1 2) (3 (4 5) 6) 7 (8) 9))	; => 5

(tree-collect 
 (lambda (tree)
   (and (list? tree) (member 5 tree)))
 '(0 (1 5) (3 (4 5) 6) 7 (5) 9))	; => ((1 5) (4 5) (5))

(tree-combine + '(1 2 3) '(5 6 7))	; => (6 8 10)

(tree-combine * '(1 2 3) 5)		; => (5 10 15)

(tree-combine cons 'a '(1 2))		; => ((a . 1) (a . 2))

(tree-combine / 1 3)			; => 1/3

(tree-combine - 
	      '((1 2) (3 4)) '(7 8))	; => ((-6 -5) (-5 -4))

(tree->vector 
 '(1 (2 3 4) 5 (7 #(8 9)))) 		; => #(1 #(2 3 4) 5 #(7 #(8 9)))

(tree-clauses '(1 (2 3) (4 (5 6))))	

;; => (1 (2 3) 2 3 (4 (5 6)) 4 (5 6) 5 6)

(tree-find-clause (equal?? '(2 3)) 
		   '(1 2 3))		; => #f

(tree-find-clause (equal?? '(2 3)) 
		   '(1 (4 (2 3))))	; => (2 3)

(list->tree '(a b c d e f) '(1 (2 3) (4 (5 6))))

;; => (a (b c) (d (e f)))

(list->tree '(a b c d e f) '(1 2 3 4 5 6))

;; => (a b c d e f)

